package br.com.rookgraph.run;

import java.util.Random;

import br.com.rookgraph.GenerateGraph;
import br.com.rookgraph.Graph;
import br.com.rookgraph.utils.ControleExecucao;
import br.com.rookgraph.utils.EnumGeracaoArvore;
import br.com.rookgraph.utils.ExecuteHeuristicas;

public class RunBranchGeneratorPlus {

	public static void main(String[] args) {
		ExecuteHeuristicas algoritmo1 = ExecuteHeuristicas.PLUS2;
		ExecuteHeuristicas algoritmo2 = ExecuteHeuristicas.APPROXIMATIVE;
		
		ControleExecucao execucao = ControleExecucao.PRIMEIRA_DERROTA;
		execucao.setQtdMaximaIteracoes(100);
		
		int numV = 10;
		int dens = 10;
		
		runAlgorithms(algoritmo1, algoritmo2, execucao, numV, dens, EnumGeracaoArvore.LARGURA, EnumGeracaoArvore.KRUSKAL);
	}

	public static void runAlgorithms(ExecuteHeuristicas algoritmo1, ExecuteHeuristicas algoritmo2, ControleExecucao execucao, int numV, int incEdge, EnumGeracaoArvore arvore1, EnumGeracaoArvore arvore2) {
		int qtdBranch1 = -1, qtdBranch2 = -1;
		
		System.out.println("COMPARAÇÃO DE HEURÍSTICAS: " + algoritmo1.toString() + " vs. " + algoritmo2.toString());
		
		System.out.println( "\n *****  Resultado *****");
		System.out.println( "Grafo\t" + algoritmo1 + "\t" + algoritmo2);

		while (execucao.continua()) {
			GenerateGraph generateGraph = new GenerateGraph();
			Graph graph = generateGraph.generateWhit(numV, incEdge, false);
			int qtdBranchTreeInicial = 0;
			long tempo1;
			long tempo2;

			int raiz = new Random().nextInt(numV) + 1;
			Graph treeIni = graph.getTreeLarge(new Graph(graph.getOrder()), raiz);
			qtdBranchTreeInicial = treeIni.getBranchs().length;

			if (qtdBranchTreeInicial > 0) {
				tempo1 = System.currentTimeMillis();
				Graph result1 = algoritmo1.execute(graph, clone(treeIni));
				tempo1 = System.currentTimeMillis() - tempo1;
				
				tempo2 = System.currentTimeMillis();
				Graph result2 = algoritmo2.execute(graph, clone(treeIni));
				tempo2 = System.currentTimeMillis() - tempo2;
				
				qtdBranch1 = result1.getBranchs().length;
				qtdBranch2 = result2.getBranchs().length;
				
				// Esse if deve exibir e contabilizar somente quando foi possível fazer a redução de branches com pelo menos uma heurística
				if (qtdBranchTreeInicial > qtdBranch1 || qtdBranchTreeInicial > qtdBranch2) {	
					execucao.marcarFimIteracao(qtdBranch1, qtdBranch2, tempo1, tempo2);
					execucao.exibirDadosIteracao();
				}
			}
		}
		
		System.out.println("\n");
		System.out.println("Vitórias de " + algoritmo1 + ": " + execucao.getQtdResultado1Melhor());
		System.out.println("Vitórias de " + algoritmo2 + ": " + execucao.getQtdResultado2Melhor());
		System.out.println("Empates: " + execucao.getQtdEmpates());
		
		execucao.zerarContadores();
		
		System.out.println("\nFim.");
	}


	/**
	 * Retorna um clone do grafo passado, uma nova instancia
	 * com a mesma matriz de adjacencia.
	 *
	 * @param treeLarge
	 * @return clone da tree
	 */
	public static Graph clone(Graph graph) {
		try {
			return (Graph) graph.clone();
		} catch (CloneNotSupportedException e) {
			throw new RuntimeException(e);
		}
	}

}


